/*
 * @Descripttion:
 * @version:
 * @Author: ChenXiang
 * @Date: 2021-07-24 23:02:23
 * @LastEditors: ChenXiang
 * @LastEditTime: 2021-08-19 21:29:35
 */
import React, { useRef } from "react";

class FormStore {
  constructor(props) {
    this.store = {}; // 存储表单数据
    this.fieldEnetities = []; // 存储所有的filed
    this.callbacks = {};
  }

  componentDidMount() {
    const { registerEntity } = this.context;
    // 实现register
    registerEntity(this);
  }

  // form子组件挂载的时候就放在fieldEnetities
  registerEntity = (entity) => {
    this.fieldEnetities.push(entity);
    // 取消订阅
    return () => {
      // 过滤
      this.fieldEnetities = this.fieldEnetities.filter(
        (item) => item !== entity
      );
      delete this.store[entity.props.name];
    };
  };

  setCallback = (callback) => {
    this.callbacks = {
      ...this.callbacks,
      ...callback
    };
  };

  getFieldValue = (name) => {
    return this.store[name];
  };

  getFieldsValue = () => {
    return this.store;
  };

  validate = () => {
    const err = [];
    // todo
    this.fieldEnetities.forEach((entity) => {
      const { name, rules } = entity.props;
      const value = this.getFieldValue(name);
      const rule = rules && rules[0];
      // todo
      if (
        rule &&
        rule.required === true &&
        (value === undefined || value === "")
      ) {
        err.push({
          [name]: rule.message,
          value
        });
      }
    });
    return err;
  };

  submit = () => {
    const err = this.validate();
    const { onFinish, onFinishFailed } = this.callbacks;
    if (err.length === 0) {
      onFinish(this.getFieldsValue());
    } else if (err.length > 0) {
      onFinishFailed(err);
    }
  };

  setFieldValue = (newStore) => {
    this.store = {
      ...this.store,
      ...newStore
    };
    // 对应的组件进行更新
    this.fieldEnetities.forEach((entity) => {
      const { name } = entity.props;
      Object.keys(newStore).forEach((key) => {
        if (key === name) {
          entity.onStoreChange();
        }
      });
    });
  };

  setFieldsValue = (newStore) => {
    this.store = {
      ...this.store,
      ...newStore
    };
    this.fieldEnetities.forEach((entity) => {
      entity.onStoreChange();
    });
  };

  getForm() {
    return {
      registerEntity: this.registerEntity,
      setFieldsValue: this.setFieldsValue,
      setFieldValue: this.setFieldValue,
      getFieldValue: this.getFieldValue,
      submit: this.submit,
      setCallback: this.setCallback
    };
  }
}

export default function useForm(form) {
  // 只能实例化一次
  const formRef = useRef(null);
  if (!formRef.current) {
    if (form) {
      formRef.current = form;
    } else {
      const formStore = new FormStore();
      formRef.current = formStore.getForm();
    }
  }
  return [formRef.current];
}
